<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>闭包</title>
</head>
<body>
<script>
    //编写闭包的三个要件：
        //1.函数的嵌套
        //2.要在内部函数中引用外部函数中的变量
        //3.将内部函数作为返回值返回

    //闭包指可以访问到外部函数作用域中变量的函数

    //闭包就是用来存一些不想让外部看到的东西
    // function fn() {
    //     var a = 20;
    //     function inner() {
    //         var a = '嘻嘻嘻嘻';
    //         console.log('a = ',a);
    //         // console.log(a);
    //     }
    //     //将内部函数inner作为返回值返回
    //     return inner;
    // }
    // var t = fn();
    // t();

    // var fn2 = (function () {
    //     var times = 0;
    //     return function () {
    //         times++;
    //         console.log(times);
    //     }
    // })();
    // fn2();


    //创建闭包：
    //1.函数嵌套
    //2.内部函数引用外部函数中的变量
    //3.将内部函数作为返回值返回

    // 闭包就是可以访问外部函数(作用域)中变量的内部函数
    //闭包就是可以访问外部函数(作用域)中变量的内部函数
    //闭包就是可以访问外部函数(作用域)中变量的内部函数

    //闭包什么时候产生？
    //当调用外部函数时，闭包就已经创建了
    //外部函数每调用一次就会产生一个闭包
    //闭包和闭包之间是相互独立的

    //闭包什么时候消失？
    // 直到内部函数被垃圾回收(GC)后才消失
    // function outer() {
    //     var n = 0;
    //
    //     function inner() {
    //         n++;
    //         console.log('inner ->',n);
    //
    //     }
    //     function inner2() {
    //         n++;
    //         console.log('inner2 ->',n);
    //
    //     }
    //     //将内部函数存储到一个对象中返回
    //     return {inner:inner,inner2:inner2};
    // }
    // var obj = outer();
    // obj.inner2();
    // obj.inner();
    // obj.inner2();
    // // console.log(outer());
    // outer().inner2();
    // outer().inner();
    // outer().inner();

   //  function outer() {
   //      var n = 0;
   //      function inner() {
   //          n++;
   //          console.log('n等于 : ',n);
   //      }
   //      return inner;
   //  }
   //  var fn2 = outer();
   //  var fn3 = outer();
   // fn2();
   //  fn2();
   //  fn2();
   //  fn2();
   //  fn3();
   //  fn3();
   //  fn3();
   //  fn2();

    // var fn2 = (function () {
    //     var n = 0;
    //     return function () {
    //         n++;
    //         console.log('n等于: ',n);
    //     }
    // })();
    // fn2();
    // fn2();
    // fn2();
    // fn2();
    // fn2();

    //闭包三要件：
    // 1.必须嵌套
    // 2.内部函数必须引用外部函数的变量
    // 3.把内部函数作为返回值返回

    var a = 10;
    var inner = fn();
    inner();
    function fn() {
        var a = 20;
        console.log('fn()中打印a = ',a);
        function inner() {
            var a = '唐三藏';//没有引用外部函数的变量，所以不是闭包
            console.log('inner中打印a = ',a);
        }
        return inner;
    }
</script>
</body>
</html>